package com.bonc.apicreator.ctrl;


import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.bonc.apicreator.codebuild.utils.FreemarkerUtil;
import com.bonc.apicreator.dao.ProjectDao;
import com.bonc.apicreator.entity.Project;
import com.bonc.apicreator.swagger.action.SwaggerAction;
import com.bonc.apicreator.utils.JsonUtils;

import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.swagger.models.Swagger;


/**
 * swagger Controller
 *
 * @author liuchang
 * @version 2016年8月21日
 * @see SwaggerController
 * @since
 */

@Controller
public class SwaggerController {
    /**
     * swaggerConfig
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(SwaggerController.class);

    /**
     * swaggerAction
     */
    @Autowired
    private SwaggerAction swaggerAction;

    /**
     * projectDao
     */
    @Autowired
    private ProjectDao projectDao;

    /**
     * Description:路径
     * 
     * @param request
     * @param id
     * @return Object
     * @see
     */
    @RequestMapping("/preview/build.json")
    public @ResponseBody Object buildApiDoc(HttpServletRequest request, Long id) {
        return JSON.toJSONString(swaggerAction.buildApi(id));
    }

    /**
     * Description:页面跳转
     * 
     * @param request
     * @param model
     * @param id
     * @return String
     * @see
     */
    @RequestMapping("/preview.htm")
    public String preview(HttpServletRequest request, Model model, Long id) {
        model.addAttribute("id", id);
        return "forward:/swagger/index.jsp";
    }

    /**
     * Description: 以下为服务器端判断客户端浏览器类型的方法
     * 
     * @param request
     * @return String
     * @see
     */
    private String getBrowser(HttpServletRequest request) {
        String UserAgent = request.getHeader("USER-AGENT").toLowerCase();
        if (UserAgent != null) {
            if (UserAgent.indexOf("msie") >= 0) {
                return "IE";
            }
            if (UserAgent.indexOf("firefox") >= 0) {
                return "FF";
            }
            if (UserAgent.indexOf("safari") >= 0) {
                return "SF";
            }
        }
        return null;
    }

    /**
     * Description: 导出格式
     * 
     * @param request
     * @param session
     * @param response
     * @param projectId
     * @param docFormat
     * @throws Exception
     *             void
     * @see
     */
    @RequestMapping("/auth/apidoc/export.htm")
    public void export(HttpServletRequest request, HttpSession session,
                       HttpServletResponse response, Long projectId, String docFormat)
        throws Exception {
        Project project = projectDao.findOne(projectId);
        String title = StringUtils.isEmpty(project.getName()) ? "project" : project.getName();
        StringBuilder fileNameBuilder = new StringBuilder(title);
        if (!StringUtils.isEmpty(project.getVersion())) {
            fileNameBuilder.append("_").append(project.getVersion());
        }
        fileNameBuilder.append("." + docFormat);
        response.setCharacterEncoding("UTF-8");
        response.setContentType("multipart/form-data;charset=utf-8");
        response.setHeader("Content-Disposition",
            "attachment;fileName=" + URLEncoder.encode(fileNameBuilder.toString(), "UTF-8"));
        if ("FF".equals(getBrowser(request))) {
            String fileName = new String(fileNameBuilder.toString().getBytes("UTF-8"),
                "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);
        }

        if ("json".equals(docFormat)) {
            dealJsonFormat(response, projectId);
        }
        else {
            dealOtherFormat(response, project);
        }
    }

    /**
     * Description: 导出json格式
     * 
     * @param response
     * @param proId
     *            void
     * @see
     */
    void dealJsonFormat(HttpServletResponse response, Long proId) {
        // 文档信息
        Swagger swagger = swaggerAction.buildApi(proId);
        try {
            OutputStream outputStream = response.getOutputStream();
            byte[] content = JsonUtils.toJson(swagger).getBytes();
            outputStream.write(content);

            outputStream.close();
        }
        catch (IOException e) {
            LOGGER.error("File Not Found", e);
        }
    }

    /**
     * Description: 导出非json格式
     * 
     * @param response
     * @param project
     * @throws TemplateException
     *             void
     * @see
     */
    void dealOtherFormat(HttpServletResponse response, Project project)
        throws TemplateException {
        Map<String, Object> result = swaggerAction.buildDocTmplData(project);
        try {
            FreemarkerUtil freemarkerUtil = new FreemarkerUtil();
            Writer writer = new OutputStreamWriter(response.getOutputStream());
            Template apiDocTemplate = freemarkerUtil.getTemplate("/doc/doc.ftl");
            apiDocTemplate.process(result, writer);
            writer.close();
        }
        catch (IOException e) {
            LOGGER.error("File Not Found", e);
        }
    }
}
